<template>
  <div class="menu-container">
    <el-card>
      <template #header>
        <el-button @click="handleCreateRootMenu">新增顶级菜单</el-button>
      </template>
      <div class="menu-tree">
        <!-- :allow-drag="allowDrag" -->
        <el-tree
          :data="menus"
          :props="defaultProps"
          @node-click="handleNodeClick"
          :expand-on-click-node="false"
          highlight-current
          draggable
          node-key="id"
          :allow-drop="allowDrop"
          @node-drop="handleNodeDrop"
        >
          <!--点击节点后不展开   :expand-on-click-node="false" -->
          <template #default="{ node, data }">
            <p class="custom-item">
              <span>{{ node.label }} </span>
              <span
                ><el-button link @click="handleCreateChildMenu(data)"
                  >添加</el-button
                >
                <el-button link @click="handleRemoveMenu(data)"
                  >删除</el-button
                ></span
              >
            </p>
          </template>
        </el-tree>
      </div>
    </el-card>

    <el-card class="edit-card">
      <template #header> 编辑菜单{{ editData && editData.id }} </template>
      <editor-menu
        v-if="editData && editData.id"
        :data="editData"
        @updateEdit="handleUpdateEdit"
      />
      <span v-else>从菜单列表选择一项后，进行编辑</span>
    </el-card>
    <right-panel
      v-if="panelVisible"
      v-model="panelVisible"
      :title="panelTitle"
      :size="330"
    >
      <add-menu :data="addMenuData" @submit="submitMenuForm"></add-menu>
    </right-panel>
  </div>
</template>

<script lang="ts" setup>
import { MenuData } from "@/api/menu"
import { useReloadPage } from "@/hooks/useReloadPage"
import { ITreeItemData, useMenuStore } from "@/stores/menu"
import type Node from "element-plus/es/components/tree/src/model/node"
const { reloadPage } = useReloadPage()
const { proxy } = getCurrentInstance()!

// 拖拽节点
// interface SimplifiedTreeItem {
//   id?: number
//   name?: string
//   parent_id?: number
// }
// const menus = ref<SimplifiedTreeItem[]>([])
// const processDataTree = (data: Partial<ITreeItemData>[]) => {
//   for (let index in data) {
//     let obj = data[index]
//     menus.value.push({
//       id: obj.id,
//       name: obj.name,
//       parent_id: obj.parent_id
//     })
//     if (obj.children !== undefined && obj.children.length > 0) {
//       processDataTree(obj.children)
//     }
//   }
// }
// const organizationAfterMove = ref<ITreeItemData[]>([])
// const getOrganizationTemp = () => {
//   store.getAllMenuList().then(() => {
//     organizationAfterMove.value = menus.value
//     menus.value = []
//     processDataTree(organizationAfterMove.value)
//   })
// }
type DropType = "prev" | "inner" | "next"
// 	拖拽时判定拖动节点能否放到目标节点,return false不能拖拽
/* inner条件：
 1.根节点不能进入
 2.同一父节点下，目标节点有与被拖节点相同的名字，不能拖入
 3.目标节点内部有与被拖节点相同的名字：不能拖入
 4.其他默认允许拖入


 前后条件
1. 是否存在同一父节点下，与被拖拽的是否存在同名的，false
2. 检查被拖动节点和目标节点不在同一父级，false
3.其他默认拖
 */

const allowDrop = (draggingNode: Node, dropNode: Node, type: DropType) => {
  // 转移节点draggingNode  目标节点dropNode   置于目标节点的位置  type='prev'、'inner' 和 'next'  三个中其中一个
  // 检查目标节点是否允许拖入
  if (type === "inner") {
    // 如果拖动节点是顶级节点，不允许拖入其他节点内部
    if (
      draggingNode.data.parent_id === 0 ||
      draggingNode.data.parent_id == null
    ) {
      return false
    }
    //同名
    if (!dropNode.data.children?.length) {
      if (
        draggingNode.data.parent_id === dropNode.data.parent_id &&
        draggingNode.data.name == dropNode.data.name
      ) {
        return false
      } else {
        return true
      }
    } else if (
      dropNode.data.children?.some(
        (child: ITreeItemData) => child.name === draggingNode.data.name
      )
    ) {
      return false
    }

    return true
  } else if (type === "prev" || type === "next") {
    // 是否存在同一父节点下，与被拖拽的是否存在同名的
    const existObj = menus.value?.find(
      (obj: ITreeItemData) =>
        obj.parent_id === dropNode.data.parent_id &&
        obj.name === draggingNode.data.name &&
        obj.id !== draggingNode.data.id
    )

    if (existObj) {
      return false
    }

    // 检查被拖动节点和目标节点是否在同一父级
    if (draggingNode.data.parent_id !== dropNode.data.parent_id) {
      return false
    }
    // 默认允许拖动

    return true
  }
}
const handleNodeDrop = (before: Node, after: Node, inner: DropType) => {
  console.log("拖拽", before, after, inner)
  // 向后端传参，起始节点，目标节点，拖拽节点所在的位置
  // 更新树
  // store.updateBulkMenu()
  // changeParentOrg(before.data.id,after.data.id,inner,this.$getCookie().getUserName());
  // setTimeout(()=>{this.getOrganizationTemp()},500);
}
const handleUpdateEdit = async (data: Partial<MenuData>) => {
  store.updateMenu(data).then(() => {
    proxy?.$message.success("菜单编辑成功")
    reloadPage()
  })
}

const store = useMenuStore()
const menus = computed(() => store.state.menuTreeData)
store.getAllMenuList()

const defaultProps = {
  children: "children",
  label: "title"
}

const menuType = ref(0) // 0 顶  1 子
const panelVisible = ref(false)

const panelTitle = computed(() => {
  return menuType.value === 0 ? "添加顶级节点" : "添加子节点"
})
const addMenuData = ref<Partial<MenuData>>({})
const handleCreateRootMenu = () => {
  menuType.value = 0
  panelVisible.value = true
  addMenuData.value = {}
}
const parentData = ref<ITreeItemData | null>()
const handleCreateChildMenu = (data: ITreeItemData) => {
  menuType.value = 1
  panelVisible.value = true
  parentData.value = data
  addMenuData.value = {}
}
const resetStatus = () => {
  panelVisible.value = false
  parentData.value = null
  reloadPage()
}
// 确认添加相关（添加菜单时 主要看父节点、排序及节点其他数据）
// 排序根据父节点最大的排序值+1
const genMenuSortId = (list: ITreeItemData[]) => {
  if (list && list.length) {
    return list[list.length - 1].sort_id + 1
  }
  return 0 //默认值
}

const handleAddRootMenu = async (data: MenuData) => {
  // parent_id , sord_id
  data.parent_id = 0
  data.sort_id = genMenuSortId(menus.value) // 根节点是根据 所有的父节点来计算的， 儿子是根据爸爸有几个儿子来算的
  await store.appendMenu(data)
  proxy?.$message.success("根菜单添加成功了")
}
const genChild = (data: MenuData) => {
  const parent = parentData.value!
  if (!parent.children) {
    parent.children = []
  }
  data.sort_id = genMenuSortId(parent.children)
  data.parent_id = parent.id
  return data
}
const handleChildRootMenu = async (data: MenuData) => {
  const child = genChild(data)
  await store.appendMenu(child)
  proxy?.$message.success("子菜单添加成功了")
}
// const addMenuRef = ref()
const submitMenuForm = async (data: MenuData) => {
  try {
    if (menuType.value === 0) {
      await handleAddRootMenu({ ...data })
    } else {
      await handleChildRootMenu({ ...data })
    }
    resetStatus()
    // addMenuRef.value?.$refs.editFormRef.resetFields()
  } catch (error) {
    const errorMessage = (error as Error).message || "未知错误"
    console.error(errorMessage)
  }
}

// 删除
const handleRemoveMenu = async (data: MenuData) => {
  try {
    await proxy?.$confirm("你确定删除" + data.title + "菜单吗?", {
      type: "warning"
    })
    await store.removeMenu({
      ...data
    })
    proxy?.$message.success("菜单删除成功")
    reloadPage()
  } catch {
    proxy?.$message.info("取消菜单")
  }
}
// 编辑
const editData = ref({} as MenuData)
const handleNodeClick = (data: MenuData) => {
  editData.value = { ...data }
}
</script>

<style scoped>
.menu-container {
  display: flex;
  padding: 20px;
}

.menu-tree {
  min-width: 500px;
  height: 400px;
  overflow-y: scroll;
}

.custom-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-grow: 1;
}

.edit-card {
  flex-grow: 1;
  margin-left: 15px;
}
</style>
